package com.briup.smartcity_group1.service.impl;

import com.briup.smartcity_group1.bean.basic.Category;
import com.briup.smartcity_group1.dao.basic.CategoryMapper;
import com.briup.smartcity_group1.dao.ext.CategoryExtMapper;
import com.briup.smartcity_group1.exception.ServiceException;
import com.briup.smartcity_group1.service.ICategoryService;
import com.briup.smartcity_group1.utils.result.ResultCode;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 资讯栏目相关接口模块实现类
 * @author WangChen
 * @date 2023/1/6 14:01
 */
@Service
public class CategoryServiceImpl implements ICategoryService {

    @Autowired
    private CategoryMapper mapper;
    @Autowired
    private CategoryExtMapper extMapper;

    /**
     * 分页查询资讯信息
     *
     * @param pageNum   页码
     * @param pageSize  页面大小
     * @return 装有当前页资讯栏目信息的列表
     */
    @Override
    public PageInfo<Category> pageQueryAll(int pageNum, int pageSize) {
        PageInfo<Category> pageInfo = PageHelper.startPage(pageNum, pageSize, true).doSelectPageInfo(
                () -> extMapper.selectAll()
        );
        return pageInfo;
    }

    /**
     * 通过id删除资讯栏目
     * <p>
     * 删除栏目信息需要删除栏目下对应的所有的咨询信息以及咨询信息对应的评论信息
     * 如果栏目作为父栏目使用，需要实现将该栏目对应的所有子栏目全部删除
     * </p>
     *
     * @param id 资讯栏目id
     * @throws ServiceException 要删除的信息不存在
     */
    @Override
    public void deleteById(int id) {

        if (mapper.selectByPrimaryKey(id) == null){
            throw new ServiceException(ResultCode.CATEGORY_NOT_FOUND);
        }

        //级联删除
        mapper.deleteByPrimaryKey(id);
    }

    /**
     * 通过id批量删除资讯栏目信息
     *
     * @param ids 资讯栏目id数组
     * @throws ServiceException 待批处理数据中有部分数据不存在;
     *                          待批处理数据全不存在;
     */
    @Override
    public void batchDelete(int[] ids) {
        //未找到的数据条数
        int notFoundCount = 0;

        for (int id:
                ids) {
            if (mapper.selectByPrimaryKey(id) == null){
                notFoundCount++;
            }
            mapper.deleteByPrimaryKey(id);
        }

        //部分数据未找到时抛出异常信息
        if (notFoundCount == 0){
            return;
        }else if (notFoundCount > 0 && notFoundCount < ids.length){
            throw new ServiceException(ResultCode.CATEGORY_NOT_FOUND_BATCH_PARTLY);
        }else{
            throw new ServiceException(ResultCode.CATEGORY_NOT_FOUND_BATCH_ALL);
        }
    }

    /**
     * 新增资讯栏目信息
     *
     * @param category 要新增的资讯栏目信息
     * @throws ServiceException 序号不能为0或负值
     */
    @Override
    public void saveCategory(Category category) {

        //序号不能为0或负值
        if (category.getCategoryOrder() <= 0){
            throw new ServiceException(ResultCode.CATEGORY_SAVE_INVALID_ORDER);
        }

        //插入新信息后对表中信息重新排序
        sortAllByCurrentOrder(category);

        mapper.insertSelective(category);
    }

    /**
     * 更新资讯栏目信息
     *
     * @param category 更新后的资讯栏目信息
     * @throws ServiceException 要更新的信息不存在
     */
    @Override
    public void updateCategory(Category category) {

        int id = category.getCategoryId();
        if (null == mapper.selectByPrimaryKey(id)){
            throw new ServiceException(ResultCode.CATEGORY_NOT_FOUND);
        }

        //插入新信息后对表中信息重新排序
        sortAllByCurrentOrder(category);

        mapper.updateByPrimaryKeySelective(category);
    }

    /**
     * 查询所有栏目信息
     *
     * @return 装有所有栏目信息的列表
     */
    @Override
    public List<Category> findAll() {
        return extMapper.selectAll();
    }

    /**
     * 对数据库中资讯信息进行排序
     * <p>
     * 通过当前传入的资讯信息的序号,对数据库中全体信息重新排序
     * 序号小于当前信息的不做改变,序号大于等于当前信息的序号加1
     * 仅服务于当前实现类中对资讯信息的保存和更新方法
     * </p>
     *
     * @param category 要被保存或更新的咨询信息
     */
    private void sortAllByCurrentOrder(Category category) {

        //获取数据库中所有信息
        List<Category> categories = extMapper.selectAll();

        Category item;

        //以传入的对象的序号为界限,对数据库中对象重新排序
        for (int i = 0; i < categories.size(); i++) {

            item = categories.get(i);

            if (item.getCategoryOrder() >= category.getCategoryOrder()){
                item.setCategoryOrder(item.getCategoryOrder()+1);
            }

            mapper.updateByPrimaryKey(item);
        }

    }

}

